<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <script type="text/javascript" src="jsunit/app/jsUnitCore.js"></script>
    <script type="text/javascript" src="../src/trial.js"></script>
    <script type="text/javascript">
    
		function setUp(){
			
		}
		
		function tearDown(){
			
		}
		
		function test_substitute(){
			
			var myFunc_count = 0;
			var newFunc_count = 0;
			
			var obj = {
				myFunc: function(){
					myFunc_count++;
				}
			};
			
			var newFunc = function(){
				newFunc_count++;
			};
			
			assertEquals(0, myFunc_count);
			obj.myFunc();
			assertEquals(1, myFunc_count);
			obj.myFunc();
			assertEquals(2, myFunc_count);
						
			trial.substitute(obj, "myFunc", newFunc);

			assertEquals("substitute did not properly swap it for the right function.", 2, myFunc_count);
			assertEquals(0, newFunc_count);
			obj.myFunc();
			assertEquals(2, myFunc_count);
			assertEquals(1, newFunc_count);
			obj.myFunc();
			assertEquals(2, myFunc_count);
			assertEquals(2, newFunc_count);

		}
		
		function test_substitute_returns_trial(){
		
			var obj = {
				myFunc: function(){}
			};
			
			var newFunc = function(){};
			
			assertEquals(trial, trial.substitute(obj, "myFunc", newFunc));
			
		}
		
		function test_substitute_same_thing_twice_throws_exception(){
		
			var myFunc_count = 0;
			var newFunc_count = 0;
			
			var obj = {
				myFunc: function(){
					myFunc_count++;
				}
			};
			
			var newFunc = function(){
				newFunc_count++;
			};
		
			trial.substitute(obj, "myFunc", newFunc);
		
			if(!trial.doesThrow(
				function(){
					trial.substitute(obj, "myFunc", newFunc);
				}
			))
				fail("Substituting the same function twice should throw an exception.");
			
		}
         
        function test_unsubstitute(){
        
			var myFunc_count = 0;
			var newFunc_count = 0;
			
			var obj = {
				myFunc: function(){
					myFunc_count++;
				}
			};
			
			var newFunc = function(){
				newFunc_count++;
			};
			
			assertEquals(0, myFunc_count);
			obj.myFunc();
			assertEquals(1, myFunc_count);
			obj.myFunc();
			assertEquals(2, myFunc_count);
						
			trial.substitute(obj, "myFunc", newFunc);

			assertEquals(2, myFunc_count);
			assertEquals(0, newFunc_count);
			obj.myFunc();
			assertEquals(2, myFunc_count);
			assertEquals(1, newFunc_count);
			obj.myFunc();
			assertEquals(2, myFunc_count);
			assertEquals(2, newFunc_count);
			
			// call unsubstitute to put things back the way they were
			trial.unsubstitute(obj, "myFunc");
        
			assertEquals("unsubstitute didn't put the right function back.", 2, myFunc_count);
			assertEquals(2, newFunc_count);
			obj.myFunc();
			assertEquals(3, myFunc_count);
			assertEquals(2, newFunc_count);
			obj.myFunc();
			assertEquals(4, myFunc_count);
			assertEquals(2, newFunc_count);
        
        }
        
        function test_unsubstitute_non_substituted_method_throws_exception(){
        
        	var obj = { myFunc: function(){} };
        	
        	assertTrue("Calling unsubstitute without previously calling substitute should throw an exception.", trial.doesThrow(
        		function(){
        			trial.unsubstitute(obj, "myFunc");
        		})
        	);
        
        }
        
        function test_unsubstitute_clears_original_substitution_data(){
        
        	var obj = { myFunc: function(){ return 1; } };
        	
        	trial.substitute(obj, "myFunc", function(){ return 2; });
        
        	assertNotNull(obj._substitutions["myFunc"]);
        	
        	trial.unsubstitute(obj, "myFunc");
        	
        	assertNull(obj._substitutions["myFunc"]);
        	
        
        }
         
    </script>
</head>
<body>
</body>
</html>